import { fetchEventSource } from '@microsoft/fetch-event-source'
import { getToken } from '@/utils/auth'

const API_URL = process.env.VUE_APP_BASE_API
let controller = null
let eventSource = null

/**
 * 发送一个 SSE 请求，返回事件流
 *
 * @param {string} action - 请求的动作路径
 * @param {any} data - 要发送的数据
 * @param {Function} onOpen - 连接成功时的回调函数
 * @param {Function} onMessage - 接收到新消息时的回调函数
 * @param {Function} onError - 错误处理函数
 * @param {Function} onClose - 连接关闭时的回调函数
 * @param {Function} onDone - 数据传输完成时的回调函数
 * @returns {void}
 */
export function sendSSERequest(action, data, onOpen, onMessage, onError, onClose, onDone) {
  // 创建 AbortController 用于中止请求
  controller = new AbortController()
  try {
    eventSource = fetchEventSource(API_URL + action, {
      method: 'POST',
      openWhenHidden: true,
      headers: {
        'Content-Type': 'application/json',
        'token': getToken()
      },
      body: JSON.stringify(data),
      signal: controller.signal, // 绑定 AbortController
      onopen(response) {
        if (response.ok) {
          console.log('SEE连接已开启！')
        } else {
          throw new Error('SSE连接开启失败，请检查服务器！')
        }
        if (onOpen) { onOpen(response) }
        return response
      },
      onmessage(event) {
        const text = event.data
        if (text === '[EXCEEDED_QUOTE_LIMIT]' && onError) {
          onError(new Error('请求列队超限！'))
          cleanup()
        }
        if (text === '[DONE]') {
          // 关闭流
          cleanup()
          if (onDone) {
            onDone()
          }
          return
        }

        // 转换正文消息
        try {
          const content = parseMsg(text)
          if (content) {
            onMessage(content)
          }
        } catch (err) {
          onError(new Error(text))
        }
      },
      onerror(err) {
        cleanup()
        if (onError) { onError(err) }
        throw err
      },
      onclose() {
        cleanup()
        if (onClose) { onClose() }
      }
    })
  } catch (error) {
    console.error(error)
    if (onError) { onError(error) }
    cleanup()
  }
}


/**
 * 释放资源
 */
const cleanup = () => {
  if (eventSource) {
    eventSource = null
  }
  if (controller) {
    controller = null
  }
}

/**
 * 转换消息
 * @param text
 * @returns {*|string}
 */
const parseMsg = (text) => {
  const data = JSON.parse(text)
  // Ollama
  if (data.choices[0].text) {
    return data.choices[0].text
  }
  // DeepSeek其他模型
  if (data.choices[0].delta && data.choices[0].delta.content) {
    return data.choices[0].delta.content
  }
}
